package com.transaction.manage.service.dayEnd;

import com.transaction.common.util.ParamsUtil;
import com.transaction.manage.localMapper.*;
import com.transaction.manage.model.dto.*;
import com.transaction.manage.model.vo.HandleVo;
import com.transaction.manage.service.BusinessHandleService;
import com.transaction.manage.util.SpringUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

@Service
public class CfmHandle {

    private static Logger LOGGER = LoggerFactory.getLogger(CfmHandle.class);

    /**
     * 1、个人反洗钱确认数据
     * @param channelInfo 渠道信息
     * @param handleDate    处理日期
     * @param logCode 日志编码
     * @param stepCode 步骤编码
     * @return
     */
    public HandleVo indiFxqCfm(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        return HandleVo.ok();
    }

    /**
     * 2、机构反洗钱确认数据
     * @param channelInfo 渠道信息
     * @param handleDate    处理日期
     * @param logCode 日志编码
     * @param stepCode 步骤编码
     * @return
     */
    public HandleVo instFxqCfm(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        return HandleVo.ok();
    }

    /**
     * 3、电子合同确认数据
     * @param channelInfo 渠道信息
     * @param handleDate    处理日期
     * @param logCode 日志编码
     * @param stepCode 步骤编码
     * @return
     */
    public HandleVo elContractCfm(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if(channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null){
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();
        String receiveCode = channelInfo.getReceiveCode();

        if(StringUtils.isEmpty(channelCode)){
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        try{
            LOGGER.info("第【{}】步开始处理。。。",stepCode);

            //获得上一工作日
            MarketDateMapper marketDateMapper = SpringUtil.getBean(MarketDateMapper.class);
            String lastDay = marketDateMapper.getLastNDay(channelCode,handleDate,0);
            if(StringUtils.isEmpty(lastDay)){
                return HandleVo.error(handleDate + "日期的上一个工作日数据为空,请配置。");
            }

            ElContract43Mapper elContract43Mapper = SpringUtil.getBean(ElContract43Mapper.class);
            List<LinkedHashMap<String,Object>> elContract43List = elContract43Mapper.selectElContract43ForCfm(channelCode,lastDay);

            if(CollectionUtils.isNotEmpty(elContract43List)){
                elContract43List.forEach(v->{
                    v.put("HANDLEDATE",handleDate);
                    Integer checkStatus = MapUtils.getInteger(v,"CHECKSTATUS");
                    if(checkStatus == 0){ //失败
                        v.put("SECONDSTATUS", 2);
                        v.put("THIRDSTATUS", 2);
                    }else {
                        v.put("SECONDSTATUS", checkStatus);
                        v.put("THIRDSTATUS", checkStatus);
                    }
                    v.put("CUSTODIANCODE",receiveCode);
                    v.put("FUNDMANAGERCODE",receiveCode);
                    v.put("FLOWSTEP","stepCode_" + stepCode + ":success");
                });
            }

            businessHandleService.saveElContractCfm(channelCode,handleDate,elContract43List);

            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.ok();
        }catch(Exception e){
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode,errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.elContractCfm}<= 发生异常 => 【{}】 ,请处理。",channelCode,handleDate,errorMsg);
            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 4、非居民确认数据
     * @param channelInfo 渠道信息
     * @param handleDate    处理日期
     * @param logCode 日志编码
     * @param stepCode 步骤编码
     * @return
     */
    public HandleVo nonResidentCfm(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if(channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null){
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if(StringUtils.isEmpty(channelCode)){
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        try{
            LOGGER.info("第【{}】步开始处理。。。",stepCode);

            //获得上一工作日
            MarketDateMapper marketDateMapper = SpringUtil.getBean(MarketDateMapper.class);
            String lastDay = marketDateMapper.getLastNDay(channelCode,handleDate,0);
            if(StringUtils.isEmpty(lastDay)){
                return HandleVo.error(handleDate + "日期的上一个工作日数据为空,请配置。");
            }

            NonResidentApplyMapper nonResidentApplyMapper = SpringUtil.getBean(NonResidentApplyMapper.class);
            List<LinkedHashMap<String,Object>> nonResidentForCfmList = nonResidentApplyMapper.selectNonResidentForCfm(channelCode,lastDay);

            if(CollectionUtils.isNotEmpty(nonResidentForCfmList)){
                nonResidentForCfmList.forEach(v->{
                    v.put("HANDLEDATE",handleDate);
                    Integer checkStatus = MapUtils.getInteger(v,"CHECKSTATUS");
                    if(checkStatus == 0){ //失败
                        v.put("RETURNCODE", "9999");
                        v.put("ERRORDETAIL", MapUtils.getString(v,"ERRORMSG"));
                    }else {
                        v.put("RETURNCODE", "0000");
                    }
                    v.put("TRANSACTIONCFMDATE",handleDate.replace("-",""));
                    v.put("FLOWSTEP","stepCode_" + stepCode + ":success");
                });
            }

            businessHandleService.saveNonResidentCfm(channelCode,handleDate,nonResidentForCfmList);

            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.ok();
        }catch(Exception e){
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode,errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.nonResidentCfm}<= 发生异常 => 【{}】 ,请处理。",channelCode,handleDate,errorMsg);
            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 5、账户确认数据
     * @param channelInfo 渠道信息
     * @param handleDate    处理日期
     * @param logCode 日志编码
     * @param stepCode 步骤编码
     * @return
     */
    public HandleVo accountCfm(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if(channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null){
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if(StringUtils.isEmpty(channelCode)){
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        try{
            LOGGER.info("第【{}】步开始处理。。。",stepCode);

            //获得上一工作日
            MarketDateMapper marketDateMapper = SpringUtil.getBean(MarketDateMapper.class);
            String lastDay = marketDateMapper.getLastNDay(channelCode,handleDate,0);
            if(StringUtils.isEmpty(lastDay)){
                return HandleVo.error(handleDate + "日期的上一个工作日数据为空,请配置。");
            }

            AccountApplyMapper accountApplyMapper = SpringUtil.getBean(AccountApplyMapper.class);
            List<LinkedHashMap<String,Object>> accountCfmList = accountApplyMapper.selectAccountForCfm(channelCode,lastDay);

            if(CollectionUtils.isNotEmpty(accountCfmList)){
                accountCfmList.forEach(v->{
                    v.put("HANDLEDATE",handleDate);
                    Integer checkStatus = MapUtils.getInteger(v,"CHECKSTATUS");
                    if(checkStatus == 0){ //失败
                        v.put("RETURNCODE", "9999");
                        v.put("ERRORDETAIL", MapUtils.getString(v,"ERRORMSG"));
                    }else {
                        v.put("RETURNCODE", "0000");
                    }
                    v.put("TRANSACTIONCFMDATE", handleDate.replace("-",""));
                    v.put("FROMTAFLAG", 1);
                    v.put("FLOWSTEP","stepCode_" + stepCode + ":success");
                });
            }

            businessHandleService.saveAccountCfm(channelCode,handleDate,accountCfmList);

            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.ok();
        }catch(Exception e){
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode,errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.accountCfm}<= 发生异常 => 【{}】 ,请处理。",channelCode,handleDate,errorMsg);
            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 6、交易确认数据
     * @param channelInfo 渠道信息
     * @param handleDate    处理日期
     * @param logCode 日志编码
     * @param stepCode 步骤编码
     * @return
     */
    public HandleVo transCfm(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if(channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null){
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if(StringUtils.isEmpty(channelCode)){
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        try{
            LOGGER.info("第【{}】步开始处理。。。",stepCode);

            //获得上一工作日
            MarketDateMapper marketDateMapper = SpringUtil.getBean(MarketDateMapper.class);
            String lastDay = marketDateMapper.getLastNDay(channelCode,handleDate,0);
            if(StringUtils.isEmpty(lastDay)){
                return HandleVo.error(handleDate + "日期的上一个工作日数据为空,请配置。");
            }

            List<LinkedHashMap<String,Object>> transForCfmList = new ArrayList<>();

            /**
             * 1、120数据
             * 2、错误数据
             *
             * 3、122数据
             * 4、124数据
             * 5、130数据
             * 6、142数据
             * 7、150数据
             * 8、144数据
             * 9、145数据
             */
            businessHandleService.select020AndErrorCfm(channelCode,lastDay,handleDate.replace("-",""),transForCfmList);

            transForCfmList.forEach(v->{
                v.put("HANDLEDATE",handleDate);
                v.put("FROMTAFLAG", 1);
                v.put("FLOWSTEP","stepCode_" + stepCode + ":success");
                String returnCode = MapUtils.getString(v,"RETURNCODE");
                if(!"0000".equals(returnCode)){ //失败
                    v.put("ERRORDETAIL", MapUtils.getString(v,"ERRORMSG"));
                }
            });

            businessHandleService.saveTransCfm(channelCode,handleDate,transForCfmList);

            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.ok();
        }catch(Exception e){
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode,errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.transCfm}<= 发生异常 => 【{}】 ,请处理。",channelCode,handleDate,errorMsg);
            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 7、分红确认数据
     * @param channelInfo 渠道信息
     * @param handleDate    处理日期
     * @param logCode 日志编码
     * @param stepCode 步骤编码
     * @return
     */
    public HandleVo dividendCfm(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if(channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null){
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if(StringUtils.isEmpty(channelCode)){
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        try{
            LOGGER.info("第【{}】步开始处理。。。",stepCode);

            //获得上一工作日
            MarketDateMapper marketDateMapper = SpringUtil.getBean(MarketDateMapper.class);
            String lastDay = marketDateMapper.getLastNDay(channelCode,handleDate,0);
            if(StringUtils.isEmpty(lastDay)){
                return HandleVo.error(handleDate + "日期的上一个工作日数据为空,请配置。");
            }

            NonResidentApplyMapper nonResidentApplyMapper = SpringUtil.getBean(NonResidentApplyMapper.class);
            List<LinkedHashMap<String,Object>> nonResidentForCfmList = nonResidentApplyMapper.selectNonResidentForCfm(channelCode,lastDay);

            NonResidentCfmMapper nonResidentCfmMapper = SpringUtil.getBean(NonResidentCfmMapper.class);
            //删除已存在的数据
            nonResidentCfmMapper.delete(new NonResidentCfm(channelCode,handleDate));
            if(CollectionUtils.isNotEmpty(nonResidentForCfmList)){
                nonResidentForCfmList.forEach(v->{
                    v.put("HANDLEDATE",handleDate);
                    Integer checkStatus = MapUtils.getInteger(v,"CHECKSTATUS");
                    if(checkStatus == 0){ //失败
                        v.put("RETURNCODE", "9999");
                        v.put("ERRORDETAIL", MapUtils.getString(v,"ERRORMSG"));
                    }else {
                        v.put("RETURNCODE", "0000");
                    }
                    v.put("TRANSACTIONCFMDATE",handleDate.replace("-",""));
                    v.put("FLOWSTEP","stepCode_" + stepCode + ":success");
                });
                //插入R2确认表
                nonResidentCfmMapper.insertNonResidentCfm(nonResidentForCfmList);
            }


            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.ok();
        }catch(Exception e){
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode,errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.dividendCfm}<= 发生异常 => 【{}】 ,请处理。",channelCode,handleDate,errorMsg);
            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

    /**
     * 8、对账确认数据
     * @param channelInfo 渠道信息
     * @param handleDate    处理日期
     * @param logCode 日志编码
     * @param stepCode 步骤编码
     * @return
     */
    public HandleVo reconciliationCfm(ChannelInfo channelInfo, String handleDate, String logCode, Integer stepCode){
        if(channelInfo == null || StringUtils.isEmpty(handleDate) || StringUtils.isEmpty(logCode) || stepCode == null){
            return HandleVo.error("渠道信息/处理日期/日志编码//处理步骤编码为空。");
        }

        String channelCode = channelInfo.getChannelCode();

        if(StringUtils.isEmpty(channelCode)){
            return HandleVo.error("渠道编码为空。");
        }

        BusinessHandleService businessHandleService = SpringUtil.getBean(BusinessHandleService.class);

        try{
            LOGGER.info("第【{}】步开始处理。。。",stepCode);

            //获得上一工作日
            MarketDateMapper marketDateMapper = SpringUtil.getBean(MarketDateMapper.class);
            String lastDay = marketDateMapper.getLastNDay(channelCode,handleDate,0);
            if(StringUtils.isEmpty(lastDay)){
                return HandleVo.error(handleDate + "日期的上一个工作日数据为空,请配置。");
            }

            NonResidentApplyMapper nonResidentApplyMapper = SpringUtil.getBean(NonResidentApplyMapper.class);
            List<LinkedHashMap<String,Object>> nonResidentForCfmList = nonResidentApplyMapper.selectNonResidentForCfm(channelCode,lastDay);

            NonResidentCfmMapper nonResidentCfmMapper = SpringUtil.getBean(NonResidentCfmMapper.class);
            //删除已存在的数据
            nonResidentCfmMapper.delete(new NonResidentCfm(channelCode,handleDate));
            if(CollectionUtils.isNotEmpty(nonResidentForCfmList)){
                nonResidentForCfmList.forEach(v->{
                    v.put("HANDLEDATE",handleDate);
                    Integer checkStatus = MapUtils.getInteger(v,"CHECKSTATUS");
                    if(checkStatus == 0){ //失败
                        v.put("RETURNCODE", "9999");
                        v.put("ERRORDETAIL", MapUtils.getString(v,"ERRORMSG"));
                    }else {
                        v.put("RETURNCODE", "0000");
                    }
                    v.put("TRANSACTIONCFMDATE",handleDate.replace("-",""));
                    v.put("FLOWSTEP","stepCode_" + stepCode + ":success");
                });
                //插入R2确认表
                nonResidentCfmMapper.insertNonResidentCfm(nonResidentForCfmList);
            }


            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.ok();
        }catch(Exception e){
            String errorMsg = ParamsUtil.getErrorMsg(e);
            //异步插入流程日志详情表
            businessHandleService.asyncInsertLogDetail(logCode,errorMsg);
            LOGGER.error("渠道:【{}】,处理日期:【{}】,=>{DataHandle.reconciliationCfm}<= 发生异常 => 【{}】 ,请处理。",channelCode,handleDate,errorMsg);
            LOGGER.info("第【{}】步处理结束。。。",stepCode);
            return HandleVo.error("未知异常,请【点击】查看详情。");
        }
    }

}
